#ifndef GAMEINPUT_H
#define GAMEINPUT_H

#include <OISEvents.h>
#include <OISInputManager.h>
#include <OISKeyboard.h>
#include <OISMouse.h>
#include "OgreRenderWindow.h"
#include <list>

enum InputState
{
	RELEASED = 0,
	JUST_PRESSED = 1,
	PRESSED = 2,
	JUST_RELEASED = 3
};

class InputInfo
{
public:
	int mOrder;
	InputState mState;

	InputInfo(void)
	{
		mOrder = -1;
		mState = RELEASED;
	}

	~InputInfo(void)
	{
	}
};

typedef std::list<OIS::KeyCode> ButtonList;

class GameInput: public OIS::KeyListener, public OIS::MouseListener
{
public:
	GameInput(Ogre::RenderWindow *rw);
	virtual ~GameInput(void);
	OIS::Mouse *getMouse(void);
	virtual bool keyPressed(const OIS::KeyEvent& evt);
	virtual bool keyReleased(const OIS::KeyEvent& evt);
	
	inline void keyReleasedCommand(const OIS::KeyEvent& evt);
	inline void keyPressedCommand(const OIS::KeyEvent& evt);
	
    virtual bool mouseMoved(const OIS::MouseEvent& evt);
    virtual bool mousePressed(const OIS::MouseEvent& evt, OIS::MouseButtonID id);
    virtual bool mouseReleased(const OIS::MouseEvent& evt, OIS::MouseButtonID id);
	
    inline void mouseMovedCommand(const OIS::MouseEvent& evt);
    inline void mousePressedCommand(const OIS::MouseEvent& evt, OIS::MouseButtonID id);
    inline void mouseReleasedCommand(const OIS::MouseEvent& evt, OIS::MouseButtonID id);

	void updateInput(void);
	InputInfo *getKeyInputs(void);
	InputInfo *getMouseInputs(void);
	OIS::MouseState getMouseState(void);
private:
	static const unsigned int NUMBER_KEYS = 200;
	static const unsigned int NUMBER_BUTTONS = 20;
	OIS::InputManager *mpInputManager;
	OIS::Mouse *mpMouse;
	OIS::Keyboard *mpKeyboard;
	InputInfo mKeyInputs[NUMBER_KEYS];
	InputInfo mMouseInputs[NUMBER_BUTTONS];
	OIS::MouseState mMouseState;
	ButtonList mPressedList;
	ButtonList mReleasedList;

	void updateOrder(void);
};
#endif